package net.hky365.lowcode.utils;

import cn.hutool.cache.Cache;
import cn.hutool.cache.impl.TimedCache;
import lombok.SneakyThrows;
import net.hky365.shop.framework.common.exception.ServiceException;
import net.hky365.shop.framework.common.exception.enums.GlobalErrorCodeConstants;
import net.hky365.shop.framework.common.util.CommonUtils;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.core.config.MagicFunction;
import org.ssssssss.script.annotation.Comment;
import org.ssssssss.script.annotation.Function;

import java.util.regex.Pattern;

/**
 * 参数验证器
 *
 * @author hl-king
 */
@Component
public class ParamsVerifier implements MagicFunction {
    /**
     * 正则缓存, 缓存7小时
     */
    private static final Cache<String, Pattern> REGEXP_CACHE = new TimedCache<>(1000L * 60 * 60 * 7);

    /**
     * 正则验证
     *
     * @param value  需要验证的值
     * @param regexp 正则
     */
    @Function
    @Comment("进行正则验证")
    public static boolean match(String value, String regexp) {
        if (value == null || regexp == null) {
            return false;
        }
        return REGEXP_CACHE.get(regexp, () -> Pattern.compile(regexp)).matcher(value).matches();
    }

    /**
     * 验证数据
     *
     * @param value  数据
     * @param regexp 正则
     */
    @Function
    @Comment("参数验证, 当值不为空且有正则的情况才进行正则验证")
    public static boolean require(@Comment("需要验证的参数") Object value, @Comment("是否必须") boolean require, @Comment("正则表达式, 为空则不验证") String regexp) {
        if (require && value == null) {
            return false;
        }
        if (value == null) {
            return true;
        }
        if (regexp != null) {
            return match(CommonUtils.toString(value), regexp);
        }
        return true;
    }

    /**
     * 验证数据
     *
     * @param value  数据
     * @param regexp 正则
     */
    @Function
    @Comment("参数验证, 当值不为空且有正则的情况才进行正则验证")
    public static boolean empty(@Comment("需要验证的参数") Object value, @Comment("不能为空") boolean notEmpty, @Comment("正则表达式, 为空则不验证") String regexp) {
        if (notEmpty && CommonUtils.isEmpty(value)) {
            return false;
        }
        if (value == null) {
            return true;
        }
        if (regexp != null) {
            return match(CommonUtils.toString(value), regexp);
        }
        return true;
    }

    /**
     * 验证数据
     *
     * @param value  数据
     * @param regexp 正则
     */
    @Function
    @SneakyThrows
    @Comment("参数验证, 当值不为空且有正则的情况才进行正则验证")
    public static void require(@Comment("需要验证的参数") Object value, @Comment("是否必须") boolean require, @Comment("正则表达式, 为空则不验证") String regexp, @Comment("错误信息") String error) {
        assertion(require(value, require, regexp), error);
    }

    /**
     * 验证数据
     *
     * @param value  数据
     * @param regexp 正则
     */
    @Function
    @Comment("参数验证, 当值不为空且有正则的情况才进行正则验证")
    public static void empty(@Comment("需要验证的参数") Object value, @Comment("不能为空") boolean notEmpty, @Comment("正则表达式, 为空则不验证") String regexp, @Comment("错误信息") String error) {
        assertion(empty(value, notEmpty, regexp), error);
    }

    /**
     * 断言
     *
     * @param verify 验证
     * @param error  异常|异常消息|ResultMessage
     */
    @Function
    public static void assertion(boolean verify, String error) {
        if (verify) {
            return;
        }
        throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), error);
    }

}
